#define NANOPRINTF_CONVERSION_BUFFER_SIZE    512
#define NANOPRINTF_CONVERSION_FLOAT_TYPE    uint16_t

#include "unit_ftoa_rev.cc"

TEST_CASE("ftoa_rev_16") {
  memset(&spec, 0, sizeof(spec));

  SUBCASE("integer overflow") {
    spec.prec = 1;
    require_ftoa_rev("65535.5", (npf_ftoa_man_t)-1 + 0.5);
    require_ftoa_rev("65536.0", (npf_ftoa_man_t)-1 + 0.96875);
    require_ftoa_rev("65540.0", (npf_ftoa_man_t)-1 + 1.);
    require_ftoa_rev("65540.0", (npf_ftoa_man_t)-1 + 1.5);
    require_ftoa_rev("65540.0", (npf_ftoa_man_t)-1 + 9.);
    require_ftoa_rev("65550.0", (npf_ftoa_man_t)-1 + 10.);
  }

  SUBCASE("fraction accuracy") {
    spec.prec = 24 + 3;
    require_ftoa_rev("1.000122070312500000000000000", 1. + 1. / ((npf_double_bin_t)0x1 << (NPF_FTOA_MAN_BITS - 3)));
    require_ftoa_rev("0.999877929687500000000000000", 1. - 1. / ((npf_double_bin_t)0x1 << (NPF_FTOA_MAN_BITS - 3)));
    require_ftoa_rev("0.666674804687500000000000000", 2. / 3.);
    require_ftoa_rev("0.000000000000000000000666479", 2. / 3. / 1e21);
  }

  SUBCASE("limits") {
    // largest representable number
    require_ftoa_rev_bin(
      "17858000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "000000000000000000000000000000000000000000000000000000000000000000000",
      ((npf_double_bin_t)NPF_DOUBLE_EXP_MASK << NPF_DOUBLE_MAN_BITS) - 1);

    spec.prec = 325 + 3;

    // smallest normal number
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000022180175781"
      "2500000000",
      (npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS);

    // largest subnormal number
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000022180175781"
      "2500000000",
      ((npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS) - 1);

    // smallest representable numbers
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000001083007"
      "8125000000",
      (npf_double_bin_t)0x3 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));

    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000676806"
      "6406250000",
      (npf_double_bin_t)0x2 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));

    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000405883"
      "7890625000",
      (npf_double_bin_t)0x1 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));
  }
}
